/**
 * \file cmd.h
 * \brief módulo para linha de comandos
 */
# ifndef COMMAND_DEFINITION
# define COMMAND_DEFINITION

# define SPECIAL_COMMAND_EXIT "exit"
# define SPECIAL_COMMAND_LIST "help"

# define SHOW_COMMAND_PROMPT "> "
# define SHOW_COMMAND_PATTERN "%s -> %s\n"
# define SHOW_COMMAND_DOESNT_EXIST "Comando não existe"
# define SHOW_COMMAND_DOESNT_EXIST_SOLUTION "Use o comando 'help' para listar os comandos disponiveis"


# include <stdlib.h>
# include <string.h>
# include <stdio.h>
# include <ctype.h>
# include <sys/types.h>
# include <sys/file.h>
# include <sys/stat.h>
# include <sys/errno.h>
# include <readline/readline.h>
# include <readline/history.h>
# include "readline.h"
# include "../../util/lists/linked-list.h"
# include "../logs/logSystem.h"

typedef enum { FINE, NOT_EXISTS, ARGUMENT, FEW_ARGUMENTS, OVER_ARGUMENTS } CommandResultType;
typedef struct {
	char *reason;
	char *solution;
	CommandResultType type;
} CommandResult;

typedef CommandResult * (*cmdFunction)(int,char**);

typedef struct {
	char *name;
	cmdFunction command;
	char *description;
} Command;


/**
 * \brief Cria um comando novo
 * \param name Nome do comando
 * \param func função invocada aquando executado o comando
 * \param desc Descriçao do comando
 * \return Comando em memória
 */
Command * newCommand (char *name, cmdFunction func, char *desc);

/**
 * \brief Inicializa a linha de comandos
 * \param list Lista de comandos existentes
 * \param exit_cmd Nome do comando de saída (Comando especial)
 */
void initializeCommandLine(LinkedList *list);
/**
 * \brief Cria um novo resultado
 * \param reason Razão do Resultado
 * \param solution Solução (em caso de erro).
 * \param type Tipo do resultado
 * \return Comando em memória (necessário libertar se não for mais usada).
 */
CommandResult * newCommandResult (const char *reason, const char *solution, CommandResultType type);
/**
 * \brief Resultado quando tudo corre bem!
 */
CommandResult * successCommandResult ();
/**
 * \brief Coloca a linha de comandos à espera do input do utilizador.
 */
void promptUser ();
/**
 * \brief Coloca a linha de comandos à espera controlando o estado.
 */
void promptUserCicle ();

/**
 * \brief Diz se o comando que o utilizador digitou foi o exit!
 */
int isDone ();
/**
 * \brief diz para terminar!
 */
void setDone ();
/** 
 * \brief liberda da memoria esta estrutura
 * \param cmd REsultado
 */
void freeCommandResult (CommandResult *cmd);

# endif
